#!/usr/bin/env python3
"""
DSL语法优化脚本 - 第二阶段
主要优化内容：
1. 标准化数据类型 (decimal->number, date->datetime, text->string, json->object)
2. 处理enum类型定义和引用
3. 优化重复的字段定义
4. 简化冗余的description字段
"""

import os
import re
import yaml
import sys
from pathlib import Path
from collections import defaultdict

def load_yaml_file(file_path):
    """加载YAML文件"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return yaml.safe_load(f)
    except Exception as e:
        print(f"❌ 无法加载文件 {file_path}: {e}")
        return None

def save_yaml_file(file_path, data):
    """保存YAML文件"""
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
        return True
    except Exception as e:
        print(f"❌ 无法保存文件 {file_path}: {e}")
        return False

def standardize_data_types(attributes):
    """标准化数据类型"""
    type_mappings = {
        'decimal': 'number',
        'date': 'datetime',
        'text': 'string',
        'json': 'object'
    }
    
    changes = []
    
    for attr_name, attr_def in attributes.items():
        if 'type' in attr_def:
            old_type = attr_def['type']
            if old_type in type_mappings:
                new_type = type_mappings[old_type]
                attr_def['type'] = new_type
                changes.append(f"    🔄 标准化类型 '{old_type}' -> '{new_type}': {attr_name}")
    
    return changes

def process_enum_types(data):
    """处理enum类型定义和引用"""
    changes = []
    
    # 收集所有enum定义
    enums = {}
    if 'enums' in data:
        enums = data['enums']
    
    # 处理实体中的enum类型
    if 'entities' in data:
        for entity_name, entity_def in data['entities'].items():
            if 'attributes' in entity_def:
                for attr_name, attr_def in entity_def['attributes'].items():
                    if attr_def.get('type') == 'enum':
                        # 检查是否有values定义
                        if 'values' in attr_def:
                            # 如果有values，保持现状
                            continue
                        elif 'enum' in attr_def:
                            # 如果有enum引用，转换为values
                            enum_ref = attr_def['enum']
                            if enum_ref in enums:
                                attr_def['values'] = enums[enum_ref]
                                del attr_def['enum']
                                changes.append(f"    🔄 转换enum引用为values: {entity_name}.{attr_name}")
                        else:
                            # 如果既没有values也没有enum引用，添加默认值
                            attr_def['values'] = ['active', 'inactive']
                            changes.append(f"    ➕ 添加默认enum值: {entity_name}.{attr_name}")
    
    return changes

def optimize_common_fields(entities):
    """优化重复的字段定义"""
    changes = []
    
    # 定义标准字段模板
    standard_fields = {
        'id': {
            'type': 'uuid',
            'rules': ['required'],
            'description': '唯一标识'
        },
        'createdAt': {
            'type': 'datetime',
            'rules': ['required'],
            'description': '创建时间'
        },
        'updatedAt': {
            'type': 'datetime',
            'rules': [],
            'description': '更新时间'
        }
    }
    
    for entity_name, entity_def in entities.items():
        if 'attributes' not in entity_def:
            continue
            
        attributes = entity_def['attributes']
        
        for field_name, standard_def in standard_fields.items():
            if field_name in attributes:
                current_def = attributes[field_name]
                
                # 检查是否需要标准化
                needs_update = False
                updates = {}
                
                # 检查类型
                if current_def.get('type') != standard_def['type']:
                    updates['type'] = standard_def['type']
                    needs_update = True
                
                # 检查规则
                current_rules = current_def.get('rules', [])
                if current_rules != standard_def['rules']:
                    updates['rules'] = standard_def['rules']
                    needs_update = True
                
                # 检查描述（如果当前没有描述或描述过于简单）
                current_desc = current_def.get('description', '')
                if not current_desc or len(current_desc) < 3:
                    updates['description'] = standard_def['description']
                    needs_update = True
                
                if needs_update:
                    attributes[field_name].update(updates)
                    changes.append(f"    🔧 标准化字段 '{field_name}': {entity_name}")
    
    return changes

def simplify_descriptions(attributes):
    """简化冗余的description字段"""
    changes = []
    
    # 定义常见的冗余描述模式
    redundant_patterns = [
        (r'^用户.*', '用户相关字段'),
        (r'^系统.*', '系统字段'),
        (r'^.*标识$', '标识字段'),
        (r'^.*时间$', '时间字段'),
        (r'^.*状态$', '状态字段'),
    ]
    
    for attr_name, attr_def in attributes.items():
        if 'description' in attr_def:
            desc = attr_def['description']
            
            # 检查是否是冗余描述
            for pattern, replacement in redundant_patterns:
                if re.match(pattern, desc) and len(desc) > 10:
                    # 如果描述过长且匹配模式，可以考虑简化
                    # 但为了保持信息完整性，这里只标记，不实际修改
                    changes.append(f"    ℹ️  可简化描述: {attr_name} ('{desc}')")
                    break
    
    return changes

def process_file(file_path):
    """处理单个YAML文件"""
    print(f"\n📝 处理文件: {os.path.basename(file_path)}")
    
    # 创建备份
    backup_path = f"{file_path}.backup-phase2"
    try:
        with open(file_path, 'r', encoding='utf-8') as src, open(backup_path, 'w', encoding='utf-8') as dst:
            dst.write(src.read())
    except Exception as e:
        print(f"❌ 无法创建备份: {e}")
        return False
    
    # 加载YAML数据
    data = load_yaml_file(file_path)
    if not data:
        return False
    
    total_changes = []
    
    # 处理enum类型
    enum_changes = process_enum_types(data)
    total_changes.extend(enum_changes)
    
    # 处理每个实体
    if 'entities' in data:
        for entity_name, entity_def in data['entities'].items():
            print(f"  🔧 优化实体: {entity_name}")
            entity_changes = []
            
            # 标准化数据类型
            if 'attributes' in entity_def:
                type_changes = standardize_data_types(entity_def['attributes'])
                entity_changes.extend(type_changes)
                
                # 简化描述（仅分析，不修改）
                desc_changes = simplify_descriptions(entity_def['attributes'])
                entity_changes.extend(desc_changes)
            
            total_changes.extend(entity_changes)
            
            # 打印实体的修改
            for change in entity_changes:
                print(change)
        
        # 优化通用字段（在所有实体处理完后）
        common_changes = optimize_common_fields(data['entities'])
        total_changes.extend(common_changes)
        
        # 打印通用字段优化
        if common_changes:
            print("  🔧 优化通用字段:")
            for change in common_changes:
                print(change)
    
    # 保存修改后的文件
    if save_yaml_file(file_path, data):
        print(f"✅ {os.path.basename(file_path)} 优化完成")
        return True
    else:
        # 恢复备份
        try:
            with open(backup_path, 'r', encoding='utf-8') as src, open(file_path, 'w', encoding='utf-8') as dst:
                dst.write(src.read())
        except:
            pass
        return False

def main():
    if len(sys.argv) != 2:
        print("用法: python3 fix-dsl-syntax-phase2.py <models_directory>")
        sys.exit(1)
    
    models_dir = Path(sys.argv[1])
    if not models_dir.exists():
        print(f"❌ 目录不存在: {models_dir}")
        sys.exit(1)
    
    print("🚀 开始第二阶段DSL语法优化...")
    print("=" * 50)
    
    # 查找所有YAML文件（排除备份文件）
    yaml_files = []
    for file_path in models_dir.glob("*.yml"):
        if not any(backup_suffix in file_path.name for backup_suffix in ['.backup', '.backup-phase1', '.backup-phase1-additional', '.backup-phase2']):
            yaml_files.append(file_path)
    
    if not yaml_files:
        print("❌ 未找到YAML文件")
        sys.exit(1)
    
    success_count = 0
    processed_files = []
    
    # 处理每个文件
    for file_path in sorted(yaml_files):
        if process_file(file_path):
            success_count += 1
            processed_files.append(file_path.name)
    
    # 输出总结
    print("\n" + "=" * 50)
    print("📊 第二阶段DSL语法优化完成")
    print("=" * 50)
    print(f"✅ 成功处理: {success_count} 个文件")
    for file_name in processed_files:
        print(f"   - {file_name}")
    
    print(f"\n🔧 主要优化内容:")
    print(f"   - 🔄 标准化数据类型 (decimal->number, date->datetime, text->string, json->object)")
    print(f"   - 🔄 处理enum类型定义和引用")
    print(f"   - 🔧 优化重复的字段定义")
    print(f"   - ℹ️  分析冗余的description字段")
    
    print(f"\n💾 备份文件已创建（.backup-phase2后缀）")
    print(f"📝 建议运行语法检查: npx tsx src/cli/syntax-check.ts models")
    print(f"🔄 如需恢复: find models -name '*.backup-phase2' -exec sh -c 'mv \"$1\" \"${{1%.backup-phase2}}\"' _ {{}} \\;")

if __name__ == "__main__":
    main()